#include "comm.hpp"

class Init
{
public:
    Init()
    {
        key = GetKey();
        shmid = CreateShm(key);
        s = (char*)shmat(shmid, nullptr, 0);
    }

    ~Init()
    {
        shmdt(s);
        shmctl(shmid, IPC_RMID, nullptr);
    }
public:
    key_t key;
    int shmid;
    char *s;
};


int main()
{
    Init init;  // 生成共享内存对象

Start:
    int fd = open(filename.c_str(), O_RDONLY);
    if (fd < 0)
    {
        std::cerr << "errno: " << errno << ", errstring: " << strerror(errno) << std::endl;
        if (MakeFifo()) goto Start;
        else return 1;  // 创建失败
    }

    // TODO
    while(true)
    {
        // wait 同步版
        int code = 0;
        ssize_t n = read(fd, &code, sizeof(code));
        if (n > 0)
        {
            std::cout << "共享内存中的内容: " << init.s << std::endl;
        }
        else if (n == 0)
        {
            // 客户端退出，服务端也退出
            break;
        }


        // // 直接读取
        // std::cout << "共享内存中的内容: " << init.s << std::endl;
        // sleep(1);
    }
    // key_t key = GetKey();
    // std::cout << "key: " << ToHex(key) << std::endl;

    // // key vs shmid
    // // key: 不要在应用层使用，只用来在内核中标识shm的唯一性！
    // // shmid: 应用这个共享内存的时候，我们使用shmid来操作共享内存。
    // std::cout << "创建共享内存" << std::endl;
    // int shmid = shmget(key, size, IPC_CREAT|IPC_EXCL|0644);
    // if (shmid < 0)
    // {
    //     std::cerr << "errno: " << errno << ", errstring" << strerror(errno) << std::endl;
    //     exit(1);
    // }
    // std::cout << shmid << std::endl;
    // sleep(3);

    // // 挂接
    // std::cout << "开始将shm映射到进程的地址空间中" << std::endl;
    // char *s = (char*)shmat(shmid, nullptr, 0);
    // sleep(3);

    // // 去关联
    // std::cout << "将shm从进程地址空间中移除" << std::endl;
    // shmdt(s);
    // sleep(3);

    // // 删除共享内存
    // std::cout << "将shm从内核中删除" << std::endl;
    // shmctl(shmid, IPC_RMID, nullptr);
    // sleep(3);
    // sleep(10);
    close(fd);
    return 0;
}

